﻿using Microsoft.Extensions.DependencyInjection;

namespace 依赖注入
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var services = new ServiceCollection();

            //services.AddScoped<IConfig, Config>();

            // 切换到从数据库获取配置
            services.AddScoped<IConfig, ConfigDb>();

            services.AddScoped<IStorage, StorageImpl>();
            services.AddScoped<ILog, LogImpl>();
            services.AddScoped<Controller>();
            using (var serviceProvider = services.BuildServiceProvider())
            {
                //第一个对象，只能使用ServiceLocator模式获取，其他对象都可以通过构造函数注入获取
                var controller = serviceProvider.GetRequiredService<Controller>();
                controller.Process("Sample Data");  
            }
        }
    }

    class Controller
    {
        private readonly IStorage _storage;
        private readonly ILog _log;
        public Controller(IStorage storage, ILog log)
        {
            _storage = storage;
            _log = log;
        }

        public void Process(string data)
        {
            _log.Log("Processing data...");
            _storage.SaveData(data);
            _log.Log("Data processed successfully.");
        }
    }

    interface IConfig
    {
        string GetSetting(string key);
    }

    class Config : IConfig
    {
        public string GetSetting(string key)
        {
            // 模拟从配置文件或环境变量中获取设置
            return "SomeSettingValue";
        }
    }

    class ConfigDb : IConfig
    {
        public string GetSetting(string key)
        {
            // 模拟从数据库中获取设置
            return "DbSettingValue";
        }
    }

    interface IStorage
    {
        void SaveData(string data);
    }

    class StorageImpl : IStorage
    {
        private readonly IConfig _config;
        public StorageImpl(IConfig config)
        {
            _config = config;
        }
        public void SaveData(string data)
        {
            Console.WriteLine(_config.GetSetting("StoragePath")); 
            Console.WriteLine($"Data '{data}' has been saved.");
        }
    }

    interface ILog
    {
        void Log(string message);
    }

    class LogImpl : ILog
    {
        public void Log(string message)
        {
            Console.WriteLine($"Log: {message}");
        }
    }
}
